[XEN][POWERPC] Allocate Xen memory area based on the amount of memory
authorJimi Xenidis <jimix@watson.ibm.com>
Fri, 29 Sep 2006 18:31:05 +0000 (14:31 -0400)
committerJimi Xenidis <jimix@watson.ibm.com>
Fri, 29 Sep 2006 18:31:05 +0000 (14:31 -0400)
This will make sure that there is enough memory for large HTABs, as well as:
 - enables "xenheap_megabytes=" cmdline option
 - consistently reports on memory system
 - reduces noise in memory.c
Signed-off-by: Jimi Xenidis <jimix@watson.ibm.com>
Signed-off-by: Hollis Blanchard <hollisb@us.ibm.com>
--HG--
extra : transplant_source : %C7%FA%7CA%B9%E6%0C%DD%DD%F9%0F%ED%DE%A8%C1_%01_Ck

xen/arch/powerpc/domain_build.c
xen/arch/powerpc/memory.c
xen/arch/powerpc/setup.c

index cc439ae51d535c6d33cfbb2651ec41af11d07a07..12d9c5776ef7ade7d5ec9329eac5f9b9417f4615 100644 (file)
@@ -178,8 +178,7 @@ int construct_dom0(struct domain *d,
         shadow_set_allocation(d, opt_dom0_shadow, &preempt);
     } while (preempt);
     if (shadow_get_allocation(d) == 0)
-        panic("shadow allocation failed 0x%x < 0x%x\n",
-              shadow_get_allocation(d), opt_dom0_shadow);
+        panic("shadow allocation failed: %dMib\n", opt_dom0_shadow);
 
     ASSERT( image_len < rma_sz );
 
index c4a0102bc37833fd4c102d58250f95941c7f8732..b9928e5e6064eaa893f0efe3ba30219e75500059 100644 (file)
 #include "oftree.h"
 #include "rtas.h"
 
+#undef DEBUG
+#ifdef DEBUG
+#define DBG(fmt...) printk(fmt)
+#else
+#define DBG(fmt...)
+#endif
+
+/*
+ * opt_xenheap_megabytes: Size of Xen heap in megabytes, excluding the
+ * page_info table and allocation bitmap.
+ */
+static unsigned int opt_xenheap_megabytes = XENHEAP_DEFAULT_MB;
+integer_param("xenheap_megabytes", opt_xenheap_megabytes);
+
 unsigned long xenheap_phys_end;
+static uint nr_pages;
+static ulong xenheap_size;
+static ulong save_start;
+static ulong save_end;
+
 struct membuf {
     ulong start;
     ulong size;
@@ -34,31 +53,23 @@ typedef void (*walk_mem_fn)(struct membuf *, uint);
 
 static ulong free_xenheap(ulong start, ulong end)
 {
-    ulong save_start;
-    ulong save_end;
-
     start = ALIGN_UP(start, PAGE_SIZE);
     end = ALIGN_DOWN(end, PAGE_SIZE);
 
-    printk("%s: 0x%lx - 0x%lx\n", __func__, start, end);
-
-    save_start = oftree;
-    save_end = oftree_end;
-    if (rtas_base) {
-        if (save_start > rtas_base)
-            save_start = rtas_base;
-        if (save_end < rtas_end)
-            save_end = rtas_end;
-    }
+    DBG("%s: 0x%lx - 0x%lx\n", __func__, start, end);
 
     /* need to do this better */
     if (save_start <= end && save_start >= start) {
-        printk("%s:     Go around the saved area: 0x%lx - 0x%lx\n",
+        DBG("%s:     Go around the saved area: 0x%lx - 0x%lx\n",
                __func__, save_start, save_end);
         init_xenheap_pages(start, ALIGN_DOWN(save_start, PAGE_SIZE));
+        xenheap_size += ALIGN_DOWN(save_start, PAGE_SIZE) - start;
+
         init_xenheap_pages(ALIGN_UP(save_end, PAGE_SIZE), end);
+        xenheap_size += end - ALIGN_UP(save_end, PAGE_SIZE);
     } else {
         init_xenheap_pages(start, end);
+        xenheap_size += end - start;
     }
 
     return ALIGN_UP(end, PAGE_SIZE);
@@ -71,8 +82,10 @@ static void set_max_page(struct membuf *mb, uint entries)
     for (i = 0; i < entries; i++) {
         ulong end_page;
 
-        end_page = (mb[i].start + mb[i].size) >> PAGE_SHIFT;
+        printk("  %016lx: %016lx\n", mb[i].start, mb[i].size);
+        nr_pages += mb[i].size >> PAGE_SHIFT;
 
+        end_page = (mb[i].start + mb[i].size) >> PAGE_SHIFT;
         if (end_page > max_page)
             max_page = end_page;
     }
@@ -163,19 +176,42 @@ static void setup_xenheap(module_t *mod, int mcount)
 void memory_init(module_t *mod, int mcount)
 {
     ulong eomem;
-    ulong heap_start, heap_size;
-
-    printk("Physical RAM map:\n");
+    ulong heap_start;
+    ulong xh_pages;
 
     /* lets find out how much memory there is and set max_page */
     max_page = 0;
+    printk("Physical RAM map:\n");
     ofd_walk_mem((void *)oftree, set_max_page);
     eomem = max_page << PAGE_SHIFT;
 
     if (eomem == 0){
         panic("ofd_walk_mem() failed\n");
     }
-    printk("End of RAM: %luMB (%lukB)\n", eomem >> 20, eomem >> 10);
+
+    /* find the portion of memory we need to keep safe */
+    save_start = oftree;
+    save_end = oftree_end;
+    if (rtas_base) {
+        if (save_start > rtas_base)
+            save_start = rtas_base;
+        if (save_end < rtas_end)
+            save_end = rtas_end;
+    }
+
+    /* minimum heap has to reach to the end of all Xen required memory */
+    xh_pages = ALIGN_UP(save_end, PAGE_SIZE) >> PAGE_SHIFT;
+    xh_pages += opt_xenheap_megabytes << (20 - PAGE_SHIFT);
+
+    /* While we are allocating HTABS from The Xen Heap we need it to
+     * be larger */
+    xh_pages  += nr_pages >> 5;
+
+    xenheap_phys_end = xh_pages << PAGE_SHIFT;
+    printk("End of Xen Area: %luMiB (%luKiB)\n",
+           xenheap_phys_end >> 20, xenheap_phys_end >> 10);
+
+    printk("End of RAM: %luMiB (%luKiB)\n", eomem >> 20, eomem >> 10);
 
     /* Architecturally the first 4 pages are exception hendlers, we
      * will also be copying down some code there */
@@ -199,22 +235,20 @@ void memory_init(module_t *mod, int mcount)
         panic("total_pages > max_page: 0x%lx > 0x%lx\n",
               total_pages, max_page);
 
-    printk("total_pages: 0x%016lx\n", total_pages);
+    DBG("total_pages: 0x%016lx\n", total_pages);
 
     init_frametable();
     end_boot_allocator();
 
     /* Add memory between the beginning of the heap and the beginning
-     * of out text */
+     * of our text */
     free_xenheap(heap_start, (ulong)_start);
-
-    heap_size = xenheap_phys_end - heap_start;
-    printk("Xen heap: %luMB (%lukB)\n", heap_size >> 20, heap_size >> 10);
-
     setup_xenheap(mod, mcount);
+    printk("Xen Heap: %luMiB (%luKiB)\n",
+           xenheap_size >> 20, xenheap_size >> 10);
 
     eomem = avail_domheap_pages();
-    printk("Domheap pages: 0x%lx %luMB (%lukB)\n", eomem,
+    printk("Dom Heap: %luMiB (%luKiB)\n",
            (eomem << PAGE_SHIFT) >> 20,
            (eomem << PAGE_SHIFT) >> 10);
 }
index 4769d1ef143202caf56830407638ce99edfc550e..bfa59ca48113e6079673055f098630cf958bf2f6 100644 (file)
@@ -290,9 +290,6 @@ static void __init __start_xen(multiboot_info_t *mbi)
     /* let synchronize until we really get going */
     console_start_sync();
 
-    /* we give the first RMA to the hypervisor */
-    xenheap_phys_end = rma_size(cpu_default_rma_order_pages());
-
     /* Check that we have at least one Multiboot module. */
     if (!(mbi->flags & MBI_MODULES) || (mbi->mods_count == 0)) {
         panic("FATAL ERROR: Require at least one Multiboot module.\n");